/**
 *	@project:	kybernetes
 *	@author:	D.Toepel
 *	@note:		---
 *	
 *	Copyright (C) 2009  D.Toepel <de.dtools> {at} <gmail> {dot} <com>
 *	
 *	This program is free software: you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation, either version 3 of the License, or
 *	(at your option) any later version.
 *	
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *	
 *	You should have received a copy of the GNU General Public License
 *	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *	
 */
package dt.htwk.extras;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.sql.Driver;
import java.util.Hashtable;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.ListModel;
import javax.swing.SwingConstants;
import javax.swing.border.TitledBorder;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import dt.htwk.core.KCStartup;
import dt.htwk.res.Resource;

/**
 * <blockquote> <h3>LanguageTools</h3>
 * 
 * <pre>
 * public class LanguageTools extends JOptionPane
 * </pre>
 * <p>
 * Diese Klasse stellt ein Auswahlfenster zur Verfuegung, um die entsprechende
 * Spracheinstellung fuer das Programm zu setzen.
 * </p>
 * <p>
 * Die dafuer benoetigten Daten werden in einer XML Datei gespeichert. Diese
 * Datei wird entsprechend ausgewertet und der Inhalt als
 * <code>Hashtable&lt;String,String&gt;</code> zur Verfuegung gestellt.
 * </p>
 * </blockquote>
 * <hr>
 * <blockquote>
 * <p>
 * Beispiel
 * </p>
 * 
 * <pre>
 * Hashtable&lt;String, String&gt; lngContent = LanguageTools.showDialog();
 * </pre>
 * 
 * </blockquote>
 * <hr>
 * 
 * @author daniel
 *         <p>
 *         letzte Aenderung: 29.08.2009
 *         </p>
 */
public class LanguageTools extends JPanel{

/* ****************************************************
 * Deklaration der Variablen und Komponenten
 * ***************************************************/

	/**
	 * serialVersionUID -- Standard: 1L
	 */
	private static final long serialVersionUID = 1L;
	
	private static String FILEPATH = Resource.getCurrPath() + File.separator + "lng";

	/**
	 * Beinhaltet vorhanden Sprachen und deren Schluessel
	 */
	private static Vector<LanguageFile> items = null;
	
	/**
	 * Beinhaltet vorhanden Sprachen und deren Schluessel
	 */
	private static Vector<LanguageFile> itemsCorr = null;

	/**
	 * 
	 */
	private static JComboBox cb;

	/**
	 * 
	 */
	private static LanguageFile selectedLng;
	
	private static LanguageFile standardLng;

	private static Document dom = null;
	private static DocumentBuilderFactory dbf;
	private static DocumentBuilder db;
	private static Element domElement;

	protected LanguageFile firstLng;

	protected LanguageFile secondLng;

	private JRadioButton rbTranslate;

	private JRadioButton rbCorrection;

	private JTextField tfName;

	private JTextField tfID;

	private JTextField tfFile;

	private JRadioButton rbCorrThis;

	private JRadioButton rbCorrNew;

	private Hashtable<String, String> firstContent;

	private Hashtable<String, String> secondContent;
	
	private Hashtable<String, String> thirdContent;

	private Hashtable<String, String> lng;

	private JLabel labelFile2;

	private JLabel labelID2;

	private JLabel labelName2;

	private JLabel labelName1;

	private JLabel labelID1;

	private JLabel labelFile1;

	private JList keyList;

	private JTextArea[] taArray;

	private JButton btnBak2Xml;
	
	private static Hashtable<String, Hashtable<String, String>> output = new Hashtable<String, Hashtable<String,String>>();
	private static Hashtable<String, Hashtable<String, String>> emptyHT = new Hashtable<String, Hashtable<String,String>>();
	
	private static Object[][] keyByGroup;

//	private static Object[][] output;

	
/* ****************************************************
 * Aufruf des Konstruktors
 * ***************************************************/

	/**
	 * @param lng
	 */
	public LanguageTools(Hashtable<String, String> lng) {
		super(new BorderLayout());
		this.lng = lng;
		initLanguages();
		initGUI();
	}

/* ****************************************************
 * PUBLIC - oeffentliche Methoden
 * ***************************************************/

	/**
	 * <h3>showDialog</h3>
	 * 
	 * <pre>
	 * public Hashtable&lt;String,String&gt; showDialog()
	 * </pre>
	 * 
	 * <blockquote>
	 * 
	 * </blockquote>
	 * 
	 * @return <code>Hashtable&lt;String,String&gt;</code>
	 * 
	 */
	public static Hashtable<String, String> showDialog() {
		
		initLanguages();
		
		Hashtable<String, String> content = new Hashtable<String, String>();

		int idx = showLanguageDialog();
		if (idx == 0) {
			content = readLanguageFile(selectedLng.getFilepath());
		} else {
			return null;
		}
		return content;
	}


/* ****************************************************
 * PRIVATE - nicht-oeffentliche Methoden
 * ***************************************************/

	/**
	 * <h3>getTitledPanel</h3>
	 * 
	 * @param titel
	 * @return
	 */
	private JPanel getTitledPanel(String titel, LayoutManager layout) {
		JPanel labelPanel = new JPanel(layout);
		labelPanel.setOpaque(false);
		labelPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory
				.createLineBorder(new java.awt.Color(110, 110, 110)), " "
				+ titel + " ", TitledBorder.LEFT, TitledBorder.TOP,
				new java.awt.Font("Verdana", 1, 12), Resource.darkMarineBlue));
		labelPanel.setPreferredSize(new Dimension(100, 20));
		return labelPanel;
	}

	/**
	 * <h3>initLanguages</h3>
	 * <p>
	 * </p>
	 */
	private static void initLanguages() {
		items = new Vector<LanguageFile>();
		itemsCorr = new Vector<LanguageFile>();
		try {
			if (standardLng == null){
				String line;
				StringBuffer sb = new StringBuffer();
				File f = File.createTempFile("lng-", ".tmp", new File(FILEPATH));
				
				BufferedReader reader = new BufferedReader ( new InputStreamReader(LanguageFile.class.getResourceAsStream("de_DE.xml")));
				while((line = reader.readLine()) != null) {sb.append(line+"\n");}
				reader.close();
				
				BufferedWriter out=new BufferedWriter ( new FileWriter(f));
				out.write(sb.toString());
				out.close();
				f.deleteOnExit();
				
				standardLng = new LanguageFile();
				standardLng.setFilepath(f.getCanonicalPath());
				standardLng.setName("Deutsch");
				standardLng.setID("de");
				standardLng.setFilename("de_DE.xml");
			}
			items.add(standardLng);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		File dir = new File(FILEPATH);
		FileFilter ff = new FileFilter() {
			public boolean accept(File f) {
				return f.getName().toLowerCase().endsWith(".xml")
						|| f.isDirectory();
			}
		};

		if (dir.isDirectory()) {
			File[] files = dir.listFiles(ff);
			for (int i = 0; i < files.length; i++) {
				try {
					String[] fileData = getInitLanguages(files[i]);
					LanguageFile lf = new LanguageFile();
					lf.setFilepath(files[i].getCanonicalPath());
					lf.setName(fileData[0]);
					lf.setID(fileData[1]);
					lf.setFilename(files[i].getName());
					items.add(lf); // new LanguageFile(files[i].getCanonicalPath(),	getInitLanguages(files[i]))
					itemsCorr.add(lf);
						
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			selectedLng = items.elementAt(0);
		}
	}

	/**
	 * <h3>showLanguageDialog</h3>
	 * 
	 * @return
	 */
	private static int showLanguageDialog() {
		int n = JOptionPane.showConfirmDialog(new JFrame(),
				new Object[] { getLanguageSelector() },
				"Please select your language.", JOptionPane.OK_CANCEL_OPTION,
				JOptionPane.PLAIN_MESSAGE, null);
		return n;
	}

	/**
	 * <h3>getLanguagePanel</h3>
	 * 
	 * @return
	 */
	private static JPanel getLanguageSelector() {
		JPanel panel = new JPanel(new BorderLayout());
		panel.setSize(400, 300);
		{
			cb = new JComboBox(items);
			cb.addItemListener(new ItemListener() {

				@Override
				public void itemStateChanged(ItemEvent e) {
					if (!cb.isEditable())
						selectedLng = (LanguageFile) e.getItem();
				}
			});
			panel.add(cb);
		}
		return panel;
	}

	/**
	 * <h3>getInitLanguages</h3>
	 * 
	 * @param file
	 * @return
	 */
	public static String[] getInitLanguages(File file) {
		String[] string = new String[2];

		if (parseFile(file)) {
			string[0] = domElement.getAttribute("name");
			string[1] = domElement.getAttribute("id");
		}

		return string;
	}

	/**
	 * <h3>readLanguageFile</h3>
	 * 
	 * @param filepath
	 * @return
	 */
	private static Hashtable<String, String> readLanguageFile(String filepath) {
		Hashtable<String, String> ht = new Hashtable<String, String>();
		if (parseFile(new File(filepath))) {
			ht = getLanguageContent();
		}
		return ht;
	}
	
	/**
	 * <h3>parseFile</h3>
	 * 
	 * @param file
	 * @return
	 */
	private static Boolean parseFile(File file) {
		try {
			dbf = DocumentBuilderFactory.newInstance();
			db = dbf.newDocumentBuilder();
			dom = db.parse(file);
			domElement = dom.getDocumentElement();
			return true;
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
			return false;
		} catch (SAXException e) {
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * <h3>getLanguageContent</h3>
	 * 
	 * @return
	 */
	private static Hashtable<String, String> getLanguageContent() {
		Hashtable<String, String> ht = new Hashtable<String, String>();
		NodeList groupList = domElement.getElementsByTagName("group");
		Integer counter = groupList.getLength();
		keyByGroup = new Object[counter][2];
		
		for (int i = 0; i < counter; i++) {
			Node entry = groupList.item(i);
			Element entryElement = (Element) entry;
			NodeList entryList = entryElement.getElementsByTagName("entity");

			Hashtable<String, String> tempKeys = new Hashtable<String, String>();
			String[] keys = new String[entryList.getLength()];
			for (int j = 0; j < entryList.getLength(); j++) {
				Element entity = (Element) entryList.item(j);
				ht.put(entity.getAttribute("key"), entity.getTextContent());
				tempKeys.put(entity.getAttribute("key"), "");
				keys[j] = entity.getAttribute("key");
			}
			output.put(entryElement.getAttribute("name"), tempKeys);
			emptyHT.put(entryElement.getAttribute("name"), tempKeys);
			keyByGroup[i][0] = entryElement.getAttribute("name");
			keyByGroup[i][1] = keys;
		}
		
		return ht;
	}

	/**
	 * <h3>getLngPanel</h3>
	 * 
	 * @return
	 */
	private void initGUI() {

		// header
		JPanel header = new JPanel(new BorderLayout());
		header.setBorder(BorderFactory.createEmptyBorder(8,8,8,8));
		{
			JPanel box;
			JLabel label;
			box = new JPanel(new BorderLayout());
			label = new JLabel(lng.get("tp-lng"));
			label.setFont(new java.awt.Font("Verdana", 1, 16));
			box.add(label, BorderLayout.PAGE_START);
			label = new JLabel("Kybernetes Cup  -  HTWK Leipzig");
			label.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
			label.setHorizontalAlignment(SwingConstants.RIGHT);
			box.add(label, BorderLayout.PAGE_END);
			header.add(box, BorderLayout.EAST);
			
		}
		
		// Einstellungen
		JPanel optPanel = new JPanel(new GridBagLayout());
		optPanel.setBorder(BorderFactory.createEmptyBorder(10,2,2,2));
		{
			GridBagConstraints g = new GridBagConstraints();
			GridBagConstraints b = new GridBagConstraints();
			GridBagConstraints c = new GridBagConstraints();
			JLabel label;
			JPanel fieldPanel;

			firstLng = selectedLng;
			
			firstContent = new Hashtable<String, String>();
			firstContent = readLanguageFile(firstLng.getFilepath());
			
			secondContent = new Hashtable<String, String>();
			if (!itemsCorr.isEmpty()){
				secondLng = itemsCorr.elementAt(0);
				secondContent = readLanguageFile(secondLng.getFilepath());
			}

			fieldPanel = getTitledPanel(lng.get("tp-lng-field1-sel"), new GridBagLayout());
			fieldPanel.setPreferredSize(new Dimension(300, 175));
			{
				label = new JLabel(lng.get("tp-lng-lng") + ": ");
				label.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
				{
					b.fill = GridBagConstraints.HORIZONTAL;
					fieldPanel.add(label, b);
				}
				
				label = new JLabel(lng.get("tp-lng-name") + ": ");
				label.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
				{
					b.gridy = 1;
					b.ipady = 0;
					fieldPanel.add(label, b);
				}
				
				label = new JLabel(lng.get("tp-lng-id") + ": ");
				label.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
				{
					b.gridy = 2;
					fieldPanel.add(label, b);
				}
				
				label = new JLabel(lng.get("tp-lng-file") + ": ");
				label.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
				{
					b.gridy = 3;
					fieldPanel.add(label, b);
				}
				
				labelName1 = new JLabel(firstLng.getName());
				labelName1.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
				{
					b.gridx = 1;
					b.gridy = 1;
					b.ipady = 0;
					fieldPanel.add(labelName1, b);
				}
				
				labelID1 = new JLabel(firstLng.getID());
				labelID1.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
				{
					b.gridy = 2;
					fieldPanel.add(labelID1, b);
				}
				
				labelFile1 = new JLabel(firstLng.getFilename());
				labelFile1.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
				{
					b.gridy = 3;
					fieldPanel.add(labelFile1, b);
				}

				JComboBox cbFirstLng = new JComboBox(items);
				{
					cbFirstLng.addItemListener(new ItemListener() {

						@Override
						public void itemStateChanged(ItemEvent e) {
							firstLng = (LanguageFile) e.getItem();
							firstContent = readLanguageFile(firstLng.getFilepath());
							labelName1.setText(firstLng.getName());
							labelID1.setText(firstLng.getID());
							labelFile1.setText(firstLng.getFilename());
						}
					});
					b.gridx = 1;
					b.gridy = 0;
					b.weightx = 1;
					b.fill = GridBagConstraints.HORIZONTAL;
					fieldPanel.add(cbFirstLng, b);
				}

				label = new JLabel();
				{
					b.gridy = 4;
					b.weighty = 1;
					b.fill = GridBagConstraints.VERTICAL;
					fieldPanel.add(label, b);
				}

				c.anchor = GridBagConstraints.NORTHWEST;
				optPanel.add(fieldPanel, c);
			}

			fieldPanel = getTitledPanel(lng.get("tp-lng-field2-sel"), new GridBagLayout());
			fieldPanel.setPreferredSize(new Dimension(300, 175));
			{
				b = new GridBagConstraints();

				label = new JLabel(lng.get("tp-lng-lng") + ": ");
				label.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
				{
					b.fill = GridBagConstraints.HORIZONTAL;
					fieldPanel.add(label, b);
				}

				label = new JLabel(lng.get("tp-lng-name") + ": ");
				label.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
				{
					b.gridy = 1;
					b.ipady = 0;
					fieldPanel.add(label, b);
				}
				
				label = new JLabel(lng.get("tp-lng-id") + ": ");
				label.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
				{
					b.gridy = 2;
					fieldPanel.add(label, b);
				}
				
				label = new JLabel(lng.get("tp-lng-file") + ": ");
				label.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
				{
					b.gridy = 3;
					fieldPanel.add(label, b);
				}
				
				labelName2 = new JLabel((itemsCorr.isEmpty())? "---" : secondLng.getName());
				labelName2.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
				{
					b.gridx = 1;
					b.gridy = 1;
					b.ipady = 0;
					fieldPanel.add(labelName2, b);
				}
				
				labelID2 = new JLabel((itemsCorr.isEmpty())? "---" : secondLng.getID());
				labelID2.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
				{
					b.gridy = 2;
					fieldPanel.add(labelID2, b);
				}
				
				labelFile2 = new JLabel((itemsCorr.isEmpty())? "---" : secondLng.getFilename());
				labelFile2.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
				{
					b.gridy = 3;
					fieldPanel.add(labelFile2, b);
				}

				JComboBox cbSecondLng = new JComboBox(itemsCorr);
				{
					cbSecondLng.setEnabled(!itemsCorr.isEmpty());
					if(!itemsCorr.isEmpty()){
						File f = new File(secondLng.getFilepath() + ".bak");
						if(f.exists()){
							thirdContent = readLanguageFile(secondLng.getFilepath() + ".bak");
						}else{
							thirdContent = readLanguageFile(secondLng.getFilepath());
						}
					}
					cbSecondLng.addItemListener(new ItemListener() {

						@Override
						public void itemStateChanged(ItemEvent e) {
							secondLng = (LanguageFile) e.getItem();
							secondContent = readLanguageFile(secondLng.getFilepath());
							labelName2.setText(secondLng.getName());
							labelID2.setText(secondLng.getID());
							labelFile2.setText(secondLng.getFilename());
							File f = new File(secondLng.getFilepath() + ".bak");
							btnBak2Xml.setEnabled(f.exists());
							if(f.exists()){
								thirdContent = readLanguageFile(secondLng.getFilepath() + ".bak");
							}else{
								System.out.println(secondLng.getFilepath());
								thirdContent = readLanguageFile(secondLng.getFilepath());
							}
						}
					});
					b.gridx = 1;
					b.gridy = 0;
					b.weightx = 1;
					b.fill = GridBagConstraints.HORIZONTAL;
					fieldPanel.add(cbSecondLng, b);
				}

				label = new JLabel();
				{
					b.gridy = 4;
					b.weighty = 1;
					b.fill = GridBagConstraints.VERTICAL;
					fieldPanel.add(label, b);
				}

				c.gridy = 1;
				optPanel.add(fieldPanel, c);
			}

			fieldPanel = getTitledPanel(lng.get("tp-lng-field3-sel"), new GridBagLayout());
			fieldPanel.setPreferredSize(new Dimension(400, 350));
			{
				b = new GridBagConstraints();

				rbTranslate = new JRadioButton(lng.get("tp-lng-field3-rb1"));
				rbTranslate.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 5));
				rbTranslate.setFont(new java.awt.Font("Verdana", 1, 12));
				rbTranslate.setForeground(Resource.darkGray);
				rbTranslate.setSelected(itemsCorr.isEmpty());
				{
					b.weightx = 0.5;
					b.gridwidth = 2;
					b.anchor = GridBagConstraints.WEST;
					b.fill = GridBagConstraints.HORIZONTAL;
					fieldPanel.add(rbTranslate, b);
				}

				rbCorrection = new JRadioButton(lng.get("tp-lng-field3-rb2"));
				rbCorrection.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 5));
				rbCorrection.setFont(new java.awt.Font("Verdana", 1, 12));
				rbCorrection.setForeground(Resource.darkGray);
				rbCorrection.setSelected(!itemsCorr.isEmpty());
				rbCorrection.setEnabled(!itemsCorr.isEmpty());
				{
					b.gridy = 5;
					fieldPanel.add(rbCorrection, b);
				}

				label = new JLabel(lng.get("tp-lng-name") + " :");
				label.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
				{
					b.gridx = 0;
					b.gridy = 1;
					b.gridwidth = 1;
					b.weightx = 0;
					b.insets = new Insets(2, 20, 2, 2);
					fieldPanel.add(label, b);
				}

				label = new JLabel(lng.get("tp-lng-id") + " :");
				label.setBorder(BorderFactory.createEmptyBorder(1, 5, 1, 5));
				{
					b.gridy = 2;
					fieldPanel.add(label, b);
				}

				label = new JLabel(lng.get("tp-lng-file") + " :");
				label.setBorder(BorderFactory.createEmptyBorder(1, 5, 1, 5));
				{
					b.gridy = 3;
					fieldPanel.add(label, b);
				}

				tfName = new JTextField();
				{
					b.gridx = 1;
					b.gridy = 1;
					b.gridwidth = 1;
					b.insets = new Insets(0, 0, 0, 0);
					fieldPanel.add(tfName, b);
				}

				tfID = new JTextField();
				{
					b.gridy = 2;
					fieldPanel.add(tfID, b);
				}

				tfFile = new JTextField();
				{
					b.gridy = 3;
					fieldPanel.add(tfFile, b);
				}

				rbCorrThis = new JRadioButton(lng.get("tp-lng-field3-rb3"));
				rbCorrThis.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 5));
				rbCorrThis.setEnabled(!itemsCorr.isEmpty());
				{
					b.gridx = 0;
					b.insets = new Insets(2, 20, 2, 2);
					b.gridy = 6;
					b.gridwidth = 2;
					fieldPanel.add(rbCorrThis, b);
				}

				rbCorrNew = new JRadioButton(lng.get("tp-lng-field3-rb4"));
				rbCorrNew.setSelected(true);
				rbCorrNew.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 5));
				rbCorrNew.setEnabled(!itemsCorr.isEmpty());
				{
					b.gridy = 7;
					fieldPanel.add(rbCorrNew, b);
				}
				
				btnBak2Xml = new JButton(lng.get("tp-lng-btnbak2xml"));
				{
					btnBak2Xml.setEnabled(rbCorrection.isEnabled());
					if(!itemsCorr.isEmpty()){
						File f = new File(secondLng.getFilepath() + ".bak");
						btnBak2Xml.setEnabled(f.exists());
					}
					btnBak2Xml.addActionListener(new ActionListener() {
						
						@Override
						public void actionPerformed(ActionEvent arg0) {
							writeBak2Xml();
						}
					});
					b.anchor = GridBagConstraints.WEST;
					b.gridy = 8;
					b.fill = GridBagConstraints.NONE;
					fieldPanel.add(btnBak2Xml, b);
				}

				label = new JLabel("<html>" + lng.get("tp-lng-field3-text1") + "</html>");
				label.setVerticalAlignment(SwingConstants.TOP);
				label.setFont(new java.awt.Font("Verdana", 0, 12));
				{
					b.gridx = 2;
					b.gridy = 1;
					b.weightx = 1;
					b.gridheight = 3;
					b.fill = GridBagConstraints.BOTH;
					fieldPanel.add(label, b);
				}
				
				label = new JLabel("<html>" + lng.get("tp-lng-field3-text2") + "</html>");
				label.setVerticalAlignment(SwingConstants.TOP);
				label.setFont(new java.awt.Font("Verdana", 0, 12));
				{
					b.gridy = 6;
					fieldPanel.add(label, b);
				}

				label = new JLabel();
				{
					b.gridy = 4;
					b.weighty = 0.2;
					b.gridheight = 1;
					b.fill = GridBagConstraints.VERTICAL;
					fieldPanel.add(label, b);
				}
				
				label = new JLabel();
				{
					b.gridy = 9;
					b.weighty = 0.8;
					b.fill = GridBagConstraints.VERTICAL;
					fieldPanel.add(label, b);
				}

				ButtonGroup bg1 = new ButtonGroup();
				bg1.add(rbTranslate);
				bg1.add(rbCorrection);

				ButtonGroup bg2 = new ButtonGroup();
				bg2.add(rbCorrThis);
				bg2.add(rbCorrNew);

				c.gridx = 1;
				c.gridy = 0;
				c.weightx = 1;
				c.gridheight = 2;
				c.fill = GridBagConstraints.HORIZONTAL;
				optPanel.add(fieldPanel, c);
			}
			
			fieldPanel = getTitledPanel(lng.get("tp-lng-field4"), new BorderLayout());
			{
				label = new JLabel("<html>" + lng.get("tp-lng-field4-text") + "</html>");
				label.setVerticalAlignment(SwingConstants.TOP);
				label.setFont(new java.awt.Font("Verdana", 0, 12));
				label.setBorder(BorderFactory.createEmptyBorder(8,8,8,8));
				{
					fieldPanel.add(label, BorderLayout.CENTER);
				}
				
				c.gridx = 0;
				c.gridy = 2;
				c.weightx = 1;
				c.weighty = 1;
				c.gridwidth = 2;
				c.gridheight = 1;
				c.fill = GridBagConstraints.BOTH;
				optPanel.add(fieldPanel, c);
			}
			
			JPanel btnPanel = new JPanel();
			btnPanel.setAlignmentX(SwingConstants.RIGHT);
			{
				JButton btnSetLanguage = new JButton(lng.get("tp-lng-btn1"));
				btnSetLanguage.setAlignmentX(SwingConstants.RIGHT);
				btnSetLanguage.addActionListener(new ActionListener() {
					
					@Override
					public void actionPerformed(ActionEvent arg0) {
						saveChanges(arg0);
					}
				});
				btnPanel.add(btnSetLanguage);
				
				JButton btnReset = new JButton(lng.get("tp-lng-btn2"));
				btnReset.setAlignmentX(SwingConstants.RIGHT);
				btnReset.addActionListener(new ActionListener() {
					
					@Override
					public void actionPerformed(ActionEvent e) {
						for (int i = 0; i < keyByGroup.length; i++) {
							Hashtable<String, String> ht = output.get(keyByGroup[i][0]);
							String[] keys = (String[]) keyByGroup[i][1];
							
							for (String string : keys) {
								ht.put(string, "");
							}
							taArray[i].setText("");
							output.put((String) keyByGroup[i][0], ht);
						}
					}
				});
				btnPanel.add(btnReset);
				
				c.gridx = 0;
				c.gridy = 3;
				c.weightx = 1;
				c.weighty = 0;
				c.gridwidth = 2;
				c.anchor = GridBagConstraints.EAST;
				c.fill = GridBagConstraints.NONE;
				optPanel.add(btnPanel, c);
			}

		}

		final JTabbedPane lngPanel = new JTabbedPane();
		lngPanel.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Resource.darkGray));
		lngPanel.setTabPlacement(JTabbedPane.LEFT);

		JPanel panel;

		NodeList groupList = domElement.getElementsByTagName("group");
		taArray = new JTextArea[groupList.getLength()];
		
		for (int i = 0; i < groupList.getLength(); i++) {
			Node entry = groupList.item(i);
			Element entryElement = (Element) entry;
			NodeList entryList = entryElement.getElementsByTagName("entity");
			Element groupName = (Element) groupList.item(i);

			panel = new JPanel(new GridBagLayout());
			lngPanel.addTab(groupName.getAttribute("name"), panel);
			{
				GridBagConstraints c = new GridBagConstraints();
				JPanel jpanel;
				final JTextArea lng1;
				final JTextArea lng2;
				final JTextArea lng3;

				Object[] elements = new Object[entryList.getLength()];
				for (int j = 0; j < entryList.getLength(); j++) {
					Element entity = (Element) entryList.item(j);
					elements[j] = entity.getAttribute("key");
				}

				jpanel = getTitledPanel(lng.get("tp-lng-field1"), new BorderLayout());
				{
					lng1 = new JTextArea();
					lng1.setEditable(false);
					jpanel.add(new JScrollPane(lng1), BorderLayout.CENTER);

					c.gridx = 1;
					c.gridy = 0;
					c.gridheight = 1;
					c.weightx = 0.8;
					c.weighty = 1;
					c.fill = GridBagConstraints.BOTH;
					panel.add(jpanel, c);
				}

				jpanel = getTitledPanel(lng.get("tp-lng-field2"), new BorderLayout());
				{
					lng2 = new JTextArea();
					lng2.setEditable(false);
					jpanel.add(new JScrollPane(lng2), BorderLayout.CENTER);

					c.gridx = 1;
					c.gridy = 1;
					c.gridheight = 1;
					c.weightx = 0.8;
					c.weighty = 1;
					c.fill = GridBagConstraints.BOTH;
					panel.add(jpanel, c);
				}

				jpanel = getTitledPanel(lng.get("tp-lng-field3"), new BorderLayout());
				{
					lng3 = new JTextArea();
					lng3.addCaretListener(new CaretListener() {
						
						@Override
						public void caretUpdate(CaretEvent e) {
							String group = lngPanel.getTitleAt(lngPanel.getSelectedIndex());
							String key = keyList.getModel().getElementAt(keyList.getSelectedIndex()).toString();
							
							Hashtable<String, String> ht = output.get(group);
							ht.put(key, lng3.getText());
							output.put(group, ht);
						}
					});
					taArray[i] = lng3;
					jpanel.add(new JScrollPane(lng3), BorderLayout.CENTER);

					c.gridx = 1;
					c.gridy = 2;
					c.gridheight = 1;
					c.weightx = 0.8;
					c.weighty = 1;
					c.fill = GridBagConstraints.BOTH;
					panel.add(jpanel, c);
				}

				jpanel = getTitledPanel(lng.get("tp-lng-key"), new BorderLayout());
				{
					final JList list = new JList(elements);
					list.setOpaque(false);
					list.addListSelectionListener(new ListSelectionListener() {

						@Override
						public void valueChanged(ListSelectionEvent e) {
							keyList = list;
							String key = list.getModel().getElementAt(
									list.getSelectedIndex()).toString();
							lng1.setText(firstContent.get(key));
							lng2.setText(secondContent.get(key));
							
							String group = lngPanel.getTitleAt(lngPanel.getSelectedIndex());
							Hashtable<String, String> ht = output.get(group);
							
							if(ht.get(key).trim().isEmpty()){
								lng3.setText(thirdContent.get(key));
							}else{
								lng3.setText(ht.get(key));
							}
						}
					});
					jpanel.add(new JScrollPane(list), BorderLayout.CENTER);

					c.gridx = 0;
					c.gridy = 0;
					c.gridheight = 3;
					c.weightx = 0.2;
					c.weighty = 1;
					c.fill = GridBagConstraints.BOTH;
					panel.add(jpanel, c);
				}

			}
		}
		
		JTabbedPane tp = new JTabbedPane();
		
		tp.addTab(lng.get("tp-lng-tab1"), optPanel);
		tp.addTab(lng.get("tp-lng-tab2"), lngPanel);

		this.add(header, BorderLayout.PAGE_START);
		this.add(tp, BorderLayout.CENTER);
	}

	/**
	 * <h3>saveChanges</h3>
	 *
	 * @param arg0
	 */
	private void saveChanges(ActionEvent arg0) {
		File file;
		if (rbTranslate.isSelected()){
			String fName = tfFile.getText();
			
			if(fName.trim().isEmpty()){
				JOptionPane.showMessageDialog(
                		new JFrame(),
                		lng.get("dlg-file-empty"), 
                		lng.get("dlg-file"), 
                		JOptionPane.INFORMATION_MESSAGE);
				tfFile.requestFocus();
				tfFile.selectAll();
				return;
			}
			
			if(!fName.toLowerCase().endsWith(".xml"))
				fName += ".xml";
			
			file = new File(FILEPATH+ File.separator + fName);
			
			if(file.exists()){
				int res = JOptionPane.showConfirmDialog(
					    this,
					    lng.get("dlg-file-exists"),
					    lng.get("dlg-file"),
					    JOptionPane.YES_NO_OPTION);

				if(res == 1){
					tfFile.requestFocus();
					tfFile.selectAll();
					return;
				}
			}
		}else{
			if(rbCorrThis.isSelected()){
				// Sprachdatei aendern
				file = new File(secondLng.getFilepath()); 
			}else{
				// Korrekturdatei anlegen bzw. aendern
				file = new File(secondLng.getFilepath() + ".bak");
			}
			
		}
		writeXML(file);
	}
	
	
	private void writeXML(File file){
    	try
		{
    		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    		DocumentBuilder dbu = dbf.newDocumentBuilder();
    		Document dom = dbu.newDocument();
    		
    		String id, name;
    		
    		if(rbTranslate.isSelected()){
    			id = tfID.getText();
    			name = tfName.getText();
    			if(id.trim().isEmpty() || name.trim().isEmpty()){
    				JOptionPane.showMessageDialog(new JFrame(),
    						lng.get("dlg-file-err-data"),
    					    lng.get("dlg-file"),
    					    JOptionPane.WARNING_MESSAGE);
    				tfName.requestFocus();
    				return;
    			}
    		}else{
    			id = secondLng.getID();
    			name = secondLng.getName();
    		}
        	
     		Element rootElement = dom.createElement("language");
     		rootElement.setAttribute("id", id);
     		rootElement.setAttribute("name", name);
    		dom.appendChild(rootElement);
    		
    		for (int i = 0; i < keyByGroup.length; i++) {
    			Element entry = dom.createElement("group");
    			{
    				rootElement.appendChild(entry);
    				entry.setAttribute("name", (String) keyByGroup[i][0]);
    				
    				String[] keys = (String[]) keyByGroup[i][1];
    				Hashtable<String, String> ht = output.get(keyByGroup[i][0]);
    				
    				for (String string : keys) {
    					Element entity = dom.createElement("entity");
    	    			{
    	    				entry.appendChild(entity);
    	    				entity.setAttribute("key", string);
    	    				if(ht.get(string).trim().isEmpty()){
    	    					if(rbTranslate.isSelected())
    	    						entity.appendChild(dom.createTextNode(firstContent.get(string)));
    	    					else
    	    						entity.appendChild(dom.createTextNode(thirdContent.get(string)));
    	    				}else{
    	    					entity.appendChild(dom.createTextNode(ht.get(string)));
    	    				}
    	    				entity.normalize();
    	    			}
					}
    			}
    			    			
    			entry.normalize();
    			
			}
    		
    		rootElement.normalize();
    		dom.normalize();

			Transformer transformer = TransformerFactory.newInstance().newTransformer();
			
			DOMSource        source = new DOMSource( dom );
			FileOutputStream os     = new FileOutputStream( file );
			StreamResult     result = new StreamResult( os );
			transformer.transform( source, result );
			os.close();
			
			btnBak2Xml.setEnabled((rbCorrNew.isSelected() && rbCorrNew.isEnabled()));
			
			String line;
			StringBuffer sb = new StringBuffer();
			try
			{
				FileInputStream fis = new FileInputStream(file);
				BufferedReader reader=new BufferedReader ( new InputStreamReader(fis));
				while((line = reader.readLine()) != null) {
					line = line.replaceAll("><", ">\n<");
					line = line.replaceAll("<group", "\t<group");
					line = line.replaceAll("</group", "\t</group");
					line = line.replaceAll("<entity", "\t\t<entity");
					sb.append(line+"\n");}
				
				reader.close();
				BufferedWriter out=new BufferedWriter ( new FileWriter(file));
				out.write(sb.toString());
				out.close();
			}
			catch (IOException e) {
				JOptionPane.showMessageDialog(new JFrame(),
						file.getName() + "\n\n" +
						lng.get("dlg-file-err") + "\n\nError: [IOException] " + e.getMessage(),
					    lng.get("dlg-file"),
					    JOptionPane.WARNING_MESSAGE);
				e.printStackTrace();
			}
			
			JOptionPane.showMessageDialog(new JFrame(),
					file.getName() + "\n\n" +
					lng.get("dlg-file-ok"),
				    lng.get("dlg-file"),
				    JOptionPane.INFORMATION_MESSAGE);
    		
	    }
		
		catch (IOException e) {
			JOptionPane.showMessageDialog(new JFrame(),
					file.getName() + "\n\n" +
					lng.get("dlg-file-err") + "\n\nError: [IOException] " + e.getMessage(),
				    lng.get("dlg-file"),
				    JOptionPane.WARNING_MESSAGE);
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			JOptionPane.showMessageDialog(new JFrame(),
					file.getName() + "\n\n" +
					lng.get("dlg-file-err") + "\n\nError: [ParserConfigurationException] " + e.getMessage(),
				    lng.get("dlg-file"),
				    JOptionPane.WARNING_MESSAGE);
			e.printStackTrace();
		} catch (Exception e) {
			JOptionPane.showMessageDialog(new JFrame(),
					file.getName() + "\n\n" +
					lng.get("dlg-file-err") + "\n\nError: " + e.toString(),
				    lng.get("dlg-file"),
				    JOptionPane.WARNING_MESSAGE);
			e.printStackTrace();
		}

    }
	
	
	private void writeBak2Xml(){
		File xmlFile = new File(secondLng.getFilepath());
		File bakFile = new File(secondLng.getFilepath() + ".bak");
		
		String line;
		StringBuffer sb = new StringBuffer();
		try
		{
			FileInputStream fis = new FileInputStream(bakFile);
			BufferedReader reader=new BufferedReader ( new InputStreamReader(fis));
			while((line = reader.readLine()) != null) {sb.append(line+"\n");}
			reader.close();
			
			BufferedWriter out=new BufferedWriter ( new FileWriter(xmlFile));
			out.write(sb.toString());
			out.close();
			
			btnBak2Xml.setEnabled(!bakFile.delete());
			
			JOptionPane.showMessageDialog(new JFrame(),
					bakFile.getName() + " --> " + xmlFile.getName() + "\n\n" +
					lng.get("dlg-file-ok"),
				    lng.get("dlg-file"),
				    JOptionPane.INFORMATION_MESSAGE);
		}
		catch (IOException e) {
			JOptionPane.showMessageDialog(new JFrame(),
					lng.get("dlg-file-err") + "\n\nError: [IOException] " + e.getMessage(),
				    lng.get("dlg-file"),
				    JOptionPane.WARNING_MESSAGE);
		}
	}

}
